0 關注者

篩選集合

資源集合可以使用 yii\data\DataFilter 組件自 2.0.13 版本起進行篩選。它允許驗證和建構通過請求傳遞的篩選條件,並且在其擴展版本 yii\data\ActiveDataFilter 的幫助下,以適用於 yii\db\QueryInterface::where() 的格式使用它們。

設定資料提供器以進行篩選

集合 章節所述,我們可以使用 資料提供器 來輸出已排序和分頁的資源列表。我們也可以使用它來篩選該列表。

$filter = new ActiveDataFilter([
    'searchModel' => 'app\models\PostSearch',
]);

$filterCondition = null;
// You may load filters from any source. For example,
// if you prefer JSON in request body,
// use Yii::$app->request->getBodyParams() below:
if ($filter->load(Yii::$app->request->get())) { 
    $filterCondition = $filter->build();
    if ($filterCondition === false) {
        // Serializer would get errors out of it
        return $filter;
    }
}

$query = Post::find();
if ($filterCondition !== null) {
    $query->andWhere($filterCondition);
}

return new ActiveDataProvider([
    'query' => $query,
]);

PostSearch 模型用於定義允許篩選的屬性和值

use yii\base\Model;

class PostSearch extends Model 
{
    public $id;
    public $title;
    
    public function rules()
    {
        return [
            ['id', 'integer'],
            ['title', 'string', 'min' => 2, 'max' => 200],            
        ];
    }
}

如果您不需要任何特殊的業務邏輯,可以使用 yii\base\DynamicModel 來代替準備獨立的模型以進行搜尋規則。

$filter = new ActiveDataFilter([
    'searchModel' => (new DynamicModel(['id', 'title']))
        ->addRule(['id'], 'integer')
        ->addRule(['title'], 'string', ['min' => 2, 'max' => 200]),
]);

定義 searchModel 是為了控制允許最終使用者的篩選條件。

篩選請求

通常期望最終使用者通過一個或多個允許的方法在請求中提供可選的篩選條件(應在 API 文件中明確說明)。例如,如果篩選是通過 POST 方法使用 JSON 處理的,則可能類似於

{
    "filter": {
        "id": {"in": [2, 5, 9]},
        "title": {"like": "cheese"}
    }
}

以上條件是

  • id 必須是 2、5 或 9
  • title 必須包含單字 cheese

作為 GET 查詢的一部分發送的相同條件是

?filter[id][in][]=2&filter[id][in][]=5&filter[id][in][]=9&filter[title][like]=cheese

您可以通過設定 yii\data\DataFilter::$filterAttributeName 來更改預設的 filter 關鍵字。

篩選控制關鍵字

允許的篩選控制關鍵字的預設列表如下

篩選控制翻譯成
AND
OR
NOT
lt <
gt >
lte <=
gte >=
eq =
neq !=
in IN
nin NOT IN
like LIKE

您可以通過擴展選項 yii\data\DataFilter::$filterControls 來擴展該列表,例如,您可以為同一個篩選器建構金鑰提供多個關鍵字,從而建立多個別名,例如

[
    'eq' => '=',
    '=' => '=',
    '==' => '=',
    '===' => '=',
    // ...
]

請記住,任何未指定的關鍵字都不會被識別為篩選控制,並且將被視為屬性名稱 - 您應避免控制關鍵字和屬性名稱之間發生衝突(例如:如果您有控制關鍵字 like 和一個名為 like 的屬性,則不可能為此類屬性指定條件)。

注意:在指定篩選控制時,請考慮您的 API 使用的實際資料交換格式。確保每個指定的控制關鍵字對於該格式都是有效的。例如,在 XML 中,標籤名稱只能以字母字元開頭,因此像 >=$gt 這樣的控制項將會破壞 XML 結構描述。

注意:當新增新的篩選控制字詞時,請確保檢查是否也需要更新 yii\data\DataFilter::$conditionValidators 和/或 yii\data\DataFilter::$operatorTypes,以便根據運算子的複雜性及其應有的工作方式來實現預期的查詢結果。

處理 Null 值

雖然在 JSON 語句中使用 null 很簡單,但如果不將文字 null 與字串 "null" 混淆,就無法使用 GET 查詢發送它。自 2.0.40 版本起,您可以使用 yii\data\DataFilter::$nullValue 選項來配置將用作文字 null 替代詞的單字(預設為 "NULL")。

屬性別名

無論您是要將屬性別名為另一個名稱,還是要篩選聯接的資料庫表,您都可以使用 yii\data\DataFilter::$attributeMap 來設定別名映射

[
    'carPart' => 'car_part', // carPart will be used to filter car_part property
    'authorName' => '{{author}}.[[name]]', // authorName will be used to filter name property of joined author table
]

ActiveController 設定篩選器

yii\rest\ActiveController 帶有一組方便的常用 REST 操作,您可以輕鬆配置這些操作,以便通過 yii\rest\IndexAction::$dataFilter 屬性也使用篩選器。一種可能的做法是使用 yii\rest\ActiveController::actions()

public function actions()
{
    $actions = parent::actions();
    
    $actions['index']['dataFilter'] = [
        'class' => \yii\data\ActiveDataFilter::class,
        'attributeMap' => [
            'clockIn' => 'clock_in',
        ],
        'searchModel' => (new DynamicModel(['id', 'clockIn']))->addRule(['id', 'clockIn'], 'integer', ['min' => 1]),
    ];
    
    return $actions;
}

現在您的集合(通過 index 操作存取)可以通過 idclockIn 屬性進行篩選。

發現錯字或您認為此頁面需要改進?
在 github 上編輯它 !